package com.byedu.controller;

import com.alibaba.fastjson.JSONObject;
import com.byedu.entity.ApiUserInfo;
import com.byedu.entity.PayBean;
import com.byedu.entity.Ticket;
import com.byedu.entity.WeiXinUserInfo;
import com.byedu.service.PayBeanService;
import com.byedu.utils.*;
import com.byedu.utils.http.HttpRequestUtil;
import org.apache.log4j.Logger;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import javax.annotation.Resource;
import javax.servlet.ServletException;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.sql.Timestamp;
import java.util.Calendar;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

@Controller
public class SSOAuthController {
    private static Logger logger = Logger.getLogger(SSOAuthController.class);
    private static final long serialVersionUID = 1L;

    /**
     * 账户信息
     */
    private static Map<String, String> accounts;

    /**
     * 单点登录标记
     */
    private static Map<String, Ticket> tickets;

    /**
     * 回收ticket线程池
     */
    private ScheduledExecutorService schedulePool;

    @PostConstruct
    public void init() {

        tickets = new ConcurrentHashMap<String, Ticket>();
        schedulePool = Executors.newScheduledThreadPool(1);
        schedulePool.scheduleAtFixedRate(new RecoverTicket(tickets), DESUtils.ticketTimeout * 60, 1, TimeUnit.MINUTES);
    }


    @RequestMapping("/SSOAuth")
    public void SSOAuth(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

        PrintWriter out = response.getWriter();
        String action = request.getParameter("action");
        if ("login".equals(action)) {
            doLogin(request, response);
        } else if ("logout".equals(action)) {
            doLogout(request, response);
        } else if ("authTicket".equals(action)) {
            authTicket(request, response);
        } else {
            System.err.println("指令错误");
            out.print("Action can not be empty！");
        }
        out.close();
    }


    @PreDestroy
    public void ondestroy() {
        if (schedulePool != null)
            schedulePool.shutdown();
    }

    private void authTicket(HttpServletRequest request, HttpServletResponse response) throws IOException {
        StringBuilder result = new StringBuilder("{");
        PrintWriter out = response.getWriter();
        String encodedTicket = request.getParameter("cookieName");

        if (encodedTicket == null) {
            result.append("\"error\":true,\"errorInfo\":\"Ticket can not be empty!\"");
        } else {
            String decodedTicket = DESUtils.decrypt(encodedTicket, DESUtils.secretKey);
            if (tickets.containsKey(decodedTicket))
                result.append("\"error\":false,\"username\":").append(tickets.get(decodedTicket).getUsername());
            else
                result.append("\"error\":true,\"errorInfo\":\"Ticket is not found!\"");
        }
        result.append("}");
        out.print(result);
    }

    private void doLogout(HttpServletRequest request, HttpServletResponse response) throws IOException {
        StringBuilder result = new StringBuilder("{");
        PrintWriter out = response.getWriter();
        String encodedTicket = request.getParameter("cookieName");
        if (encodedTicket == null) {
            result.append("\"error\":true,\"errorInfo\":\"Ticket can not be empty!\"");
        } else {
            String decodedTicket = DESUtils.decrypt(encodedTicket, DESUtils.secretKey);
            tickets.remove(decodedTicket);
            result.append("\"error\":false");
        }
        result.append("}");
        out.print(result);
    }

    private void doLogin(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {

        String username = request.getParameter("username");
        String password = request.getParameter("password");
        String pass = accounts.get(username);
        if (pass == null || !pass.equals(password)) {
            request.getRequestDispatcher("tologin?errorInfo=userId is wrong!").forward(request, response);
        } else {
            String ticketKey = UUID.randomUUID().toString().replace("-", "");
            String encodedticketKey = DESUtils.encrypt(ticketKey, DESUtils.secretKey);

            Timestamp createTime = new Timestamp(System.currentTimeMillis());
            Calendar cal = Calendar.getInstance();
            cal.setTime(createTime);
            cal.add(Calendar.MINUTE, DESUtils.ticketTimeout);
            Timestamp recoverTime = new Timestamp(cal.getTimeInMillis());
            Ticket ticket = new Ticket(username, createTime, recoverTime);

            tickets.put(ticketKey, ticket);

            String[] checks = request.getParameterValues("autoAuth");
            int expiry = -1;
            if (checks != null && "1".equals(checks[0]))
                expiry = 7 * 24 * 3600;
            Cookie cookie = new Cookie(DESUtils.cookieName, encodedticketKey);
            cookie.setSecure(DESUtils.secure);// 为true时用于https
            cookie.setMaxAge(expiry);
            cookie.setDomain(DESUtils.domainName);
            cookie.setPath("/");
            response.addCookie(cookie);

            String gotoURL = request.getParameter("gotoURL");
            if (gotoURL != null)
                response.sendRedirect(gotoURL);
        }
    }
}
